#!/usr/bin/env python
#
# Copyright 2007 Google Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#

"""
An application that 
""" 

# Import packages
import re
import urllib
import urllib2
import urlparse
import wsgiref.handlers
from google.appengine.api import urlfetch
from google.appengine.api import users
from google.appengine.ext import webapp
from google.appengine.ext.webapp import template

#Request handlers
#Define your own request handlers that extend webapp.RequestHandler
class URLInputHandler(webapp.RequestHandler):
  def __init__(self):
    self.user = users.get_current_user()
    self.templateParams = {}
    self.initTemplateParams()
    self.suffix = 'gclid=TeSt'  
      
  def initTemplateParams(self):
    pass
#      userNickname = ''
#      
#      if self.user:
#          userNickname = self.user.nickname()
#          logLabel = 'Log out'
#          logURL = users.create_logout_url('/')
#      else:
#          logLabel = 'Log in'
#          logURL = users.create_login_url('/')
#          
#      logLink = '<a href="%s">%s</a>' % (logURL, logLabel)
#      
#      self.templateParams['nick'] = userNickname
#      self.templateParams['loglink'] = logLink
      
  #Handle GET requests
  def get(self):
    self.response.out.write(template.render('templates/urltester.html', self.templateParams))


re_gatc = re.compile("""<\s*script\s*type\s*=\s*"text/javascript"\s*>\s*
var\s+gaJsHost\s*=\s*\(\s*\(\s*["']https:["']\s*==\s*document.location.protocol\)\s*\?\s*["']https://ssl.["']\s*:\s*["']http://www.["']\);\s*
document.write\(unescape\("%3Cscript\s+src='"\s*\+\s*gaJsHost\s*\+\s*"google-analytics\.com/ga\.js'\s+type='text/javascript'%3E%3C/script%3E"\)\);\s*
<\s*/script\s*>\s*
<\s*script\s+type=["']text/javascript["']\s*>\s*
\s*try\s*{\s*
\s*var\s+pageTracker\s*=\s*_gat\._getTracker\(["']UA-[0-9]+-[0-9]+["']\);\s*.*
\s*pageTracker\._trackPageview\([^)]*\);\s*.*
}\s*catch\(err\)\s*{[^}]*}<\s*/script\s*>""")

class URLProcessorHandler(webapp.RequestHandler):
  def __init__(self):
    self.templateParams = {'error_msg' : [], 'result' : False }
    self.suffix = 'gclid=TeSt' 
    #self.initTemplateParams()
  
  def get(self):
    if self.request.get('url_1'):
      self.handleInput()
    else:
      self.render()
  
  #Handle POST requests
  def post(self):
    self.handleInput()
  
  def handleInput(self):
    url = self.request.get('url_1')
    frag = ''
    
    frag_test = urlparse.urldefrag(url)
    if frag_test[1] != '':
      url = frag_test[0]
      frag = '#' + frag_test[1]
    
    parsed_url = urlparse.urlsplit(url)
    query_params = parsed_url.query
    n_query_params = len(query_params.split('&'))
    
    separator = '?'
    if n_query_params > 1:
      separator = '&'
      
    new_url = url + separator + self.suffix + frag
    
    processor = URLFetcher(new_url)
    result = processor.fetchURL()
    self.templateParams.update(result)
    
    if result['outcome'] is True:
      #Check for GATC in page
      gatc_present = False
      if re_gatc.search(result['content']) is not None:
        gatc_present = True
      else:
        self.templateParams['error_msg'].append("GATC not present or incorrectly configured on page")
      
      #Check gclid was retained in URL
      gclid_maintained = False
      if result['destination_url'].find(self.suffix) > -1:
        gclid_maintained = True
      else:
        self.templateParams['error_msg'].append('gclid=TeSt not in returned URL')
      
      if gclid_maintained and gatc_present:
        self.templateParams['result'] = True
      
    self.render()
    
  def render(self):
    print template.render('templates/urltester.html', self.templateParams)


class URLFetcher(object):
  
  def __init__(self, url=None):
    self.url = url
    self.out = {'error_msg' : [], 
                'source_url' : url, 
                'outcome' : False}

  def fetchURL(self):
    return self.process(self.url)

  def process(self, url):
    try:
      result = urlfetch.fetch(url, allow_truncated=True, follow_redirects=False, deadline=10)
    except urlfetch.InvalidURLError:
      self.out['error_msg'].append('Invalud URL format [%s]' % url)
    except urlfetch.DownloadError:
      self.out['error_msg'].append('Could not download content at %s' % url)
    except urlfetch.ResponseTooLargeError:
      self.out['error_msg'].append('The response data exceeded the maximum \
                                      allowed size [%s]' % url)
    except urlfetch.Error:
      self.out['error_msg'].append('Unknown error' % url)        
    else:
      if result.status_code == 301 or result.status_code == 302:
        new_url = result.headers['location']
        return self.process(new_url)
      elif result.status_code >= 400 and result.status_code < 600:
        self.out['error_msg'].append("Error retrieving content. \
                                      Status code: %d" % result.status_code)
      elif result.status_code == 200:
        self.out['outcome'] = True
        self.out['content'] = result.content
        self.out['content_was_truncated'] = result.content_was_truncated
      else:
        pass
      
      self.out['destination_url'] = url
      return self.out
  
#    try:
#      result = urllib2.urlopen(self.url)
#      self.out.update(result.info())
#      self.out['destination_url'] = result.geturl()
#      self.out['outcome'] = True
#      self.out['content'] = result.read()
##      print result.info()
##      print result.geturl()
#      print self.out
#      
#    except urllib2.URLError, e:
#      if hasattr(e, 'reason'):
#        self.out['error_msg'] = e.reason
#      elif hasattr(e, 'code'):
#        self.out['error_msg'] = e.code
#          
#    return self.out
    

def main():
  application = webapp.WSGIApplication([('/urltester/input', URLInputHandler),
                                        ('/urltester/processSingleURL', URLProcessorHandler)],
                                       debug=True)
  wsgiref.handlers.CGIHandler().run(application)


if __name__ == '__main__':
  main()
